﻿namespace YidanSoft.Library.EditorUtility.General
{
    using System;
    using System.Drawing;
    using YidanSoft.Library.EditorUtility.Win32;

    public class ColorUtil
    {
        private static Color backgroundColor = Color.Empty;
        private static Color borderColor = Color.Empty;
        private static Color checkedColor = Color.Empty;
        private static Color controlColor = Color.Empty;
        public static string[] KnownColorNames = new string[] { 
            "Transparent", "Black", "DimGray", "Gray", "DarkGray", "Silver", "LightGray", "Gainsboro", "WhiteSmoke", "White", "RosyBrown", "IndianRed", "Brown", "Firebrick", "LightCoral", "Maroon", 
            "DarkRed", "Red", "Snow", "MistyRose", "Salmon", "Tomato", "DarkSalmon", "Coral", "OrangeRed", "LightSalmon", "Sienna", "SeaShell", "Chocalate", "SaddleBrown", "SandyBrown", "PeachPuff", 
            "Peru", "Linen", "Bisque", "DarkOrange", "BurlyWood", "Tan", "AntiqueWhite", "NavajoWhite", "BlanchedAlmond", "PapayaWhip", "Mocassin", "Orange", "Wheat", "OldLace", "FloralWhite", "DarkGoldenrod", 
            "Cornsilk", "Gold", "Khaki", "LemonChiffon", "PaleGoldenrod", "DarkKhaki", "Beige", "LightGoldenrod", "Olive", "Yellow", "LightYellow", "Ivory", "OliveDrab", "YellowGreen", "DarkOliveGreen", "GreenYellow", 
            "Chartreuse", "LawnGreen", "DarkSeaGreen", "ForestGreen", "LimeGreen", "PaleGreen", "DarkGreen", "Green", "Lime", "Honeydew", "SeaGreen", "MediumSeaGreen", "SpringGreen", "MintCream", "MediumSpringGreen", "MediumAquaMarine", 
            "YellowAquaMarine", "Turquoise", "LightSeaGreen", "MediumTurquoise", "DarkSlateGray", "PaleTurquoise", "Teal", "DarkCyan", "Aqua", "Cyan", "LightCyan", "Azure", "DarkTurquoise", "CadetBlue", "PowderBlue", "LightBlue", 
            "DeepSkyBlue", "SkyBlue", "LightSkyBlue", "SteelBlue", "AliceBlue", "DodgerBlue", "SlateGray", "LightSlateGray", "LightSteelBlue", "CornflowerBlue", "RoyalBlue", "MidnightBlue", "Lavender", "Navy", "DarkBlue", "MediumBlue", 
            "Blue", "GhostWhite", "SlateBlue", "DarkSlateBlue", "MediumSlateBlue", "MediumPurple", "BlueViolet", "Indigo", "DarkOrchid", "DarkViolet", "MediumOrchid", "Thistle", "Plum", "Violet", "Purple", "DarkMagenta", 
            "Magenta", "Fuchsia", "Orchid", "MediumVioletRed", "DeepPink", "HotPink", "LavenderBlush", "PaleVioletRed", "Crimson", "Pink", "LightPink"
         };
        private static Color pressedColor = Color.Empty;
        private static Color selectionColor = Color.Empty;
        public static string[] SystemColorNames = new string[] { 
            "ActiveBorder", "ActiveCaption", "ActiveCaptionText", "AppWorkspace", "Control", "ControlDark", "ControlDarkDark", "ControlLight", "ControlLightLight", "ControlText", "Desktop", "GrayText", "HighLight", "HighLightText", "HotTrack", "InactiveBorder", 
            "InactiveCaption", "InactiveCaptionText", "Info", "InfoText", "Menu", "MenuText", "ScrollBar", "Window", "WindowFrame", "WindowText"
         };
        private static bool useCustomColor = false;

        private ColorUtil()
        {
        }

        private static Color CalculateColor(Color front, Color back, int alpha)
        {
            Color color = Color.FromArgb(0xff, front);
            Color color2 = Color.FromArgb(0xff, back);
            float r = color.R;
            float g = color.G;
            float b = color.B;
            float num4 = color2.R;
            float num5 = color2.G;
            float num6 = color2.B;
            float num7 = ((r * alpha) / 255f) + (num4 * (((float) (0xff - alpha)) / 255f));
            byte red = (byte) num7;
            float num9 = ((g * alpha) / 255f) + (num5 * (((float) (0xff - alpha)) / 255f));
            byte green = (byte) num9;
            float num11 = ((b * alpha) / 255f) + (num6 * (((float) (0xff - alpha)) / 255f));
            byte blue = (byte) num11;
            return Color.FromArgb(0xff, red, green, blue);
        }

        public static Color ColorFromPoint(Graphics g, int x, int y)
        {
            IntPtr hdc = g.GetHdc();
            uint color = WindowsAPI.GetPixel(hdc, x, y);
            byte rValue = GetRValue(color);
            byte gValue = GetGValue(color);
            byte bValue = GetBValue(color);
            g.ReleaseHdc(hdc);
            return Color.FromArgb(rValue, gValue, bValue);
        }

        public static Color ColorFromRGBString(string text)
        {
            Color empty = Color.Empty;
            string[] strArray = text.Split(new char[] { ',' });
            if (strArray.Length != 3)
            {
                throw new Exception("RGB color string is not well formed");
            }
            string str = strArray[0];
            string str2 = strArray[1];
            string str3 = strArray[2];
            try
            {
                int red = Convert.ToInt32(str);
                int green = Convert.ToInt32(str2);
                int blue = Convert.ToInt32(str3);
                if ((((red < 0) || (red > 0xff)) || ((green < 0) || (green > 0xff))) || ((blue < 0) || (blue > 0xff)))
                {
                    throw new Exception("Out of bounds RGB value");
                }
                empty = Color.FromArgb(red, green, blue);
                Color knownColor = Color.Empty;
                bool flag = IsKnownColor(empty, ref knownColor, true);
                if (!flag)
                {
                    flag = IsSystemColor(empty, ref knownColor);
                }
                if (flag)
                {
                    empty = knownColor;
                }
            }
            catch (InvalidCastException)
            {
                throw new Exception("Invalid RGB value");
            }
            return empty;
        }

        public static byte GetBValue(uint color)
        {
            return (byte) (color >> 0x10);
        }

        public static uint GetCOLORREF(Color color)
        {
            return RGB(color.R, color.G, color.B);
        }

        public static byte GetGValue(uint color)
        {
            return (byte) (((short) color) >> 8);
        }

        private static float getRGBValue(float n1, float n2, float hue)
        {
            if (hue > 360f)
            {
                hue -= 360f;
            }
            else if (hue < 0f)
            {
                hue += 360f;
            }
            if (hue < 60.0)
            {
                return (n1 + (((n2 - n1) * hue) / 60f));
            }
            if (hue < 180f)
            {
                return n2;
            }
            if (hue < 240f)
            {
                return (n1 + (((n2 - n1) * (240f - hue)) / 60f));
            }
            return n1;
        }

        public static byte GetRValue(uint color)
        {
            return (byte) color;
        }

        public static void HSLToRGB(float h, float s, float l, ref float r, ref float g, ref float b)
        {
            float num2;
            h = (h / 240f) * 360f;
            s /= 240f;
            l /= 240f;
            r /= 255f;
            g /= 255f;
            b /= 255f;
            if (l <= 0.5f)
            {
                num2 = l * (1f + s);
            }
            else
            {
                num2 = (l + s) - (l * s);
            }
            float num = (2f * l) - num2;
            if (s == 0f)
            {
                float num3;
                b = num3 = l;
                r = g = num3;
            }
            else
            {
                r = getRGBValue(num, num2, h + 120f);
                g = getRGBValue(num, num2, h);
                b = getRGBValue(num, num2, h - 120f);
            }
            r *= 255f;
            g *= 255f;
            b *= 255f;
        }

        public static bool IsKnownColor(Color color, ref Color knownColor, bool useTransparent)
        {
            Color empty = Color.Empty;
            bool flag = false;
            for (KnownColor color3 = (KnownColor) 0; color3 <= KnownColor.YellowGreen; color3 += 1)
            {
                empty = Color.FromKnownColor(color3);
                string name = empty.Name;
                if (!useTransparent)
                {
                    flag = name == "Transparent";
                }
                if (!(((((color.A != empty.A) || (color.R != empty.R)) || ((color.G != empty.G) || (color.B != empty.B))) || empty.IsSystemColor) || flag))
                {
                    knownColor = empty;
                    return true;
                }
            }
            return false;
        }

        public static bool IsSystemColor(Color color, ref Color knownColor)
        {
            Color empty = Color.Empty;
            for (KnownColor color3 = (KnownColor) 0; color3 <= KnownColor.YellowGreen; color3 += 1)
            {
                empty = Color.FromKnownColor(color3);
                string name = empty.Name;
                if ((((color.R == empty.R) && (color.G == empty.G)) && (color.B == empty.B)) && empty.IsSystemColor)
                {
                    knownColor = empty;
                    return true;
                }
            }
            return false;
        }

        public static uint RGB(int r, int g, int b)
        {
            return (uint) ((((byte) r) | (((byte) g) << 8)) | (((byte) b) << 0x10));
        }

        public static void RGBToHSL(int r, int g, int b, ref float h, ref float s, ref float l)
        {
            float num2 = ((float) r) / 255f;
            float num3 = ((float) g) / 255f;
            float num4 = ((float) b) / 255f;
            float num5 = Math.Max(num2, Math.Max(num3, num4));
            float num6 = Math.Min(num2, Math.Min(num3, num4));
            l = (num5 + num6) / 2f;
            if (num5 == num6)
            {
                s = 0f;
                h = 240f;
            }
            else
            {
                float num = num5 - num6;
                if (((double) l) < 0.5)
                {
                    s = num / (num5 + num6);
                }
                else
                {
                    s = num / (2f - (num5 + num6));
                }
                if (num2 == num5)
                {
                    h = (num3 - num4) / num;
                }
                else if (num3 == num5)
                {
                    h = 2f + ((num4 - num2) / num);
                }
                else if (num4 == num5)
                {
                    h = 4f + ((num2 - num3) / num);
                }
                h *= 60f;
                if (h < 0f)
                {
                    h += 360f;
                }
            }
            l *= 240f;
            s *= 240f;
            h = (h / 360f) * 240f;
        }

        public static bool UsingCustomColor
        {
            get
            {
                return useCustomColor;
            }
        }

        public static Color VSNetBackgroundColor
        {
            get
            {
                if (useCustomColor && (backgroundColor != Color.Empty))
                {
                    return backgroundColor;
                }
                return CalculateColor(SystemColors.Window, SystemColors.Control, 220);
            }
            set
            {
                useCustomColor = true;
                backgroundColor = value;
            }
        }

        public static Color VSNetBorderColor
        {
            get
            {
                if (useCustomColor && (borderColor != Color.Empty))
                {
                    return borderColor;
                }
                return SystemColors.Highlight;
            }
            set
            {
                useCustomColor = true;
                borderColor = value;
            }
        }

        public static Color VSNetCheckedColor
        {
            get
            {
                if (useCustomColor && (pressedColor != Color.Empty))
                {
                    return checkedColor;
                }
                return CalculateColor(SystemColors.Highlight, SystemColors.Window, 30);
            }
            set
            {
                useCustomColor = true;
                checkedColor = value;
            }
        }

        public static Color VSNetControlColor
        {
            get
            {
                if (useCustomColor && (controlColor != Color.Empty))
                {
                    return controlColor;
                }
                return CalculateColor(SystemColors.Control, VSNetBackgroundColor, 0xc3);
            }
            set
            {
                useCustomColor = true;
                controlColor = value;
            }
        }

        public static Color VSNetPressedColor
        {
            get
            {
                if (useCustomColor && (pressedColor != Color.Empty))
                {
                    return pressedColor;
                }
                return CalculateColor(SystemColors.Highlight, VSNetSelectionColor, 70);
            }
            set
            {
                useCustomColor = true;
                pressedColor = value;
            }
        }

        public static Color VSNetSelectionColor
        {
            get
            {
                if (useCustomColor && (selectionColor != Color.Empty))
                {
                    return selectionColor;
                }
                return CalculateColor(SystemColors.Highlight, SystemColors.Window, 70);
            }
            set
            {
                useCustomColor = true;
                selectionColor = value;
            }
        }
    }
}

